package com.jiantong.web.open.app.work;

import com.jiantong.common.util.UserUtil;
import com.jiantong.user.ext.LoginUser;
import com.jiantong.user.model.UserProfile;
import com.jiantong.user.service.BreedFactoryReadService;
import com.jiantong.web.core.enums.ExceptionCode;
import com.jiantong.work.model.ProductionReport;
import com.jiantong.work.service.ProductionReportReadService;
import com.jiantong.work.service.ProductionReportWriteService;
import io.terminus.boot.rpc.common.annotation.RpcConsumer;
import io.terminus.common.model.Paging;
import io.terminus.common.model.Response;
import io.terminus.pampas.openplatform.annotations.OpenBean;
import io.terminus.pampas.openplatform.annotations.OpenMethod;
import io.terminus.pampas.openplatform.exceptions.OPClientException;
import io.terminus.pampas.openplatform.exceptions.OPServerException;
import lombok.extern.slf4j.Slf4j;
import org.assertj.core.util.Strings;
import org.joda.time.DateTime;
import org.springframework.web.bind.annotation.RequestMethod;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 生产中心-生产记录信息表
 *
 */
@Slf4j
@OpenBean
public class ProductionReportApis {

    /**
     * 生产记录查询服务
     */
    @RpcConsumer
    private ProductionReportReadService productionReportReadService;

    @RpcConsumer
    private BreedFactoryReadService breedFactoryReadService;
    /**
     * 生产记录 增、删、改、查  服务
     */
    @RpcConsumer
    private ProductionReportWriteService productionReportWriteService;


    @OpenMethod(
            key = "find.production.report.by.id",
            paramNames = {"id"},
            httpMethods = RequestMethod.GET)
    public ProductionReport findById(Long id){
        if(id == null){
            log.error("id should be not null");
            throw new OPClientException(ExceptionCode.ID_NOT_EXIST.value(),
                    "id should be not null");
        }
        Response<ProductionReport> resp = productionReportReadService.findById(id);
        if (!resp.isSuccess()){
            log.error("failed to find feed report  by id = {}, cause : {}", id, resp.getError());
            throw new OPServerException(ExceptionCode.DATA_NOT_FOUND.value()
                    ,resp.getError());
        }
        return resp.getResult();
    }

    /**
     *
     * 新建一条单据
     * @param productionReport 生产记录对象
     * @return 返回该单据的id
     */
    @OpenMethod(
            key = "create.production.report",
            paramNames = {"productionReport","toStatus"},
            httpMethods = RequestMethod.POST)
    public  Map<String , Object> create(ProductionReport productionReport,Integer toStatus) {
        Response<Map<String , Object>> response = productionReportWriteService.create(productionReport,toStatus);
        if (!response.isSuccess()) {
            log.error("failed to create production report = {}, cause : {}", productionReport,toStatus, response.getError());
            throw new OPServerException(ExceptionCode.DATA_WRITE_FAIL.value(),
                    response.getError());
        }
        return response.getResult();
    }

    /**
     * 更新一条单据
     * @param productionReport 生产记录对象
     * @return 返回true or false
     */
    @OpenMethod(
            key = "update.production.report",
            paramNames = {"productionReport","toStatus"},
            httpMethods = RequestMethod.PUT)
    public Map<String,Object> update(ProductionReport productionReport,Integer toStatus){
        if(productionReport.getId() == null){
            log.error("id should be not null");
            throw new OPClientException(ExceptionCode.ID_NOT_EXIST.value()
                    ,"id should be not null");
        }
        Response<Map<String , Object>> statusResponse = productionReportReadService.findStatusById(productionReport.getId());
        if(statusResponse.isSuccess()
                && !statusResponse.getResult().get("status").equals(productionReport.getStatus())){
            log.error("productionReport is already submitted");
            throw new OPClientException(ExceptionCode.DOCUMENT_REPEAT_SUBMIT.value(),
                    "this.report.is.already.submitted");
        }
        Response<Map<String , Object>> response = productionReportWriteService.update(productionReport,toStatus);
        if(!response.isSuccess()){
            log.error("failed to update production report productionReport = {} ,case:{}",productionReport,response.getError());
            throw new OPServerException(ExceptionCode.DATA_WRITE_FAIL.value(),
                    response.getError());
        }
        return response.getResult();
    }
    /**
     * 养殖场状态查询
     */
    @OpenMethod(
            key = "paging.production.report",
            paramNames = {"pageNo", "pageSize","status","breedFactoryId"},
            httpMethods = RequestMethod.GET)
    public Paging<ProductionReport> pagingProductionReport(Integer pageNo,
                                                           Integer pageSize,
                                                           Integer status,
                                                           Long breedFactoryId) {
        if(breedFactoryId == null){
            log.error("breedFactoryId should be not null");
            throw new OPClientException(ExceptionCode.ID_NOT_EXIST.value(),
                    "breedFactoryId should be not null");
        }
        Response<Paging<ProductionReport>> resp =
                productionReportReadService.pagingProductionReport(pageNo, pageSize, status,breedFactoryId);
        if (!resp.isSuccess()) {
            log.error("failed to paging production report, cause : {}", resp.getError());
            throw new OPServerException(ExceptionCode.DATA_NOT_FOUND.value(),
                    resp.getError());
        }
        return resp.getResult();
    }

    /**
     * 养殖场合计 todo 是否修改
     *
     * @return status =1
     */
    @OpenMethod(
            key = "sum.combined.report",
            paramNames = {"breedFactoryId"},
            httpMethods = RequestMethod.GET)
    public Map aquacultureSum(Long breedFactoryId) {
        if(breedFactoryId == null){
            log.error("breedFactoryId should be not null");
            throw new OPClientException(ExceptionCode.ID_NOT_EXIST.value(),
                    "breedFactoryId should be not null");
        }
        Response<Map> resp = productionReportReadService.sumRestockBreedFactoryId(breedFactoryId);
        if (!resp.isSuccess()) {
            log.error("failed to sum production report, cause : {}", resp.getError());
            throw new OPServerException(ExceptionCode.DATA_NOT_FOUND.value(),
                    resp.getError());
        }
        return resp.getResult();
    }
    /**
     * 政府端时间查询
     *
     * @return status =1
     */
    @OpenMethod(
            key = "paging.status.production.report",
            paramNames = {"pageNo", "pageSize", "breedFactoryId", "breedType", "fromDate", "toDate"},
            httpMethods = RequestMethod.GET)
    public Paging<ProductionReport> pagingProductionReports(Integer pageNo,
                                                            Integer pageSize,
                                                            Long breedFactoryId,
                                                            Integer breedType,
                                                            String fromDate,
                                                            String toDate) {
        Date start = null;
        if (!Strings.isNullOrEmpty(fromDate)) {
            start = DateTime.parse(fromDate).toDate();
        }

        Date end = null;
        if (!Strings.isNullOrEmpty(toDate)) {
            end = DateTime.parse(toDate).toDate();
        }
        Response<Paging<ProductionReport>> resp = productionReportReadService
                .pagingProductionReports(pageNo, pageSize, breedFactoryId,breedType, start, end);
        if (!resp.isSuccess()) {
            log.error("failed to paging Production Report{}, cause : {}", resp.getError());
            throw new OPServerException(ExceptionCode.DATA_NOT_FOUND.value(),
                    resp.getError());
        }
        return resp.getResult();
    }


    /**
     * 按物种统计存栏数合计值
     *
     * @return status =1
     */
    @OpenMethod(
            key = "sum.animal.species",
            paramNames = {"breedFactoryId"},
            httpMethods = RequestMethod.GET)
    public List<Map<String , Object>> speciesStatistics(Long breedFactoryId) {
        Response<List<Map<String , Object>>> resp =
                productionReportReadService.sumSpeciesStatistics(breedFactoryId);
        if (!resp.isSuccess()) {
            log.error("failed to sum by animal species, cause : {}", resp.getError());
            throw new OPServerException(ExceptionCode.DATA_NOT_FOUND.value(),
                    resp.getError());
        }
        return resp.getResult();
    }

    /**
     * 根据一下参数求变动数的和
     * @param provinceId 省id
     * @param cityId 市id
     * @param regionId 区id
     * @param streetId 街道id
     * @param villageId 村庄id
     * @param isScale 是否是规模场
     * @param scale 规模类型
     * @param breedType 养殖类型
     * @param breedFactoryId 养殖场id
     * @return List<Map<String , Object>>
     */
    @OpenMethod(
            key = "sum.change.quantity.by.animal.type",
            paramNames = {"provinceId","cityId","regionId","streetId","villageId",
                    "isScale","scale","breedType","breedFactoryId"},
            httpMethods = RequestMethod.GET
    )
    public List<Map<String , Object>> sumChangeQuantityByAnimalType(Long provinceId ,Long cityId ,
                                                                    Long regionId,Long streetId,
                                                                    Long villageId,Integer isScale,
                                                                    Integer scale ,Integer breedType,
                                                                    Long breedFactoryId){
        List<Long> breedFactoryIds = new ArrayList<>();
        if(breedFactoryId != null){
            breedFactoryIds.add(breedFactoryId);
        }else {
            Response<List<Long>> listResponse =
                    breedFactoryReadService.findBreedFactoryIdsByArea(provinceId,cityId,regionId,streetId,
                            villageId,isScale,scale,breedType);
            if(!listResponse.isSuccess()){
                log.error("failed to find breed factory ids error={}",listResponse.getError());
                throw new OPServerException(ExceptionCode.DATA_NOT_FOUND.value(),listResponse.getError());
            }
            breedFactoryIds = listResponse.getResult();
        }

        Response<List<Map<String , Object>>> listResponse1 =
                productionReportReadService.sumChangeQuantityByAnimalType(breedFactoryIds);
        if(!listResponse1.isSuccess()){
            log.error("failed to sum change quantity by area error = {}",listResponse1.getError());
            throw new OPServerException(ExceptionCode.DATA_NOT_FOUND.value(),listResponse1.getError());
        }

        return listResponse1.getResult();
    }

    /**
     * 根据一下参数分页查询生产记录的列表
     * @param pageNo 页码
     * @param pageSize 每页多少条
     * @param provinceId 省id
     * @param cityId 市id
     * @param regionId 区id
     * @param streetId 街道id
     * @param villageId 村庄id
     * @param isScale 是否是规模场
     * @param scale 规模类型
     * @param breedType 养殖类型
     * @param breedFactoryId 养殖场id
     * @param fromDate 从日期
     * @param toDate 到日期
     * @return Paging<ProductionReport>
     */
    @OpenMethod(
            key = "paging.production.report.by.area",
            paramNames = {"pageNo","pageSize","provinceId","cityId","regionId","streetId","villageId",
                    "isScale","scale","breedType","breedFactoryId","fromDate","toDate"},
            httpMethods = RequestMethod.GET
    )
    public Paging<ProductionReport> pagingProductionReportByArea(Integer pageNo ,Integer pageSize,
                                                                 Long provinceId ,Long cityId ,
                                                                 Long regionId,Long streetId,
                                                                 Long villageId,Integer isScale,
                                                                 Integer scale ,Integer breedType,
                                                                 String fromDate,String toDate,
                                                                 Long breedFactoryId){
        Date start = null;
        if (!Strings.isNullOrEmpty(fromDate)) {
            start = DateTime.parse(fromDate).toDate();
        }

        Date end = null;
        if (!Strings.isNullOrEmpty(toDate)) {
            end = DateTime.parse(toDate).toDate();
        }
        List<Long> breedFactoryIds = new ArrayList<>();
        if(breedFactoryId != null){
            breedFactoryIds.add(breedFactoryId);
        }else {
            Response<List<Long>> listResponse =
                    breedFactoryReadService.findBreedFactoryIdsByArea(provinceId,cityId,regionId,streetId,
                            villageId,isScale,scale,breedType);
            if(!listResponse.isSuccess()){
                log.error("failed to find breed factory ids error = {}",listResponse.getError());
                throw new OPServerException(ExceptionCode.DATA_NOT_FOUND.value(),listResponse.getError());
            }
            breedFactoryIds = listResponse.getResult();
        }

        Response<Paging<ProductionReport>> pagingResponse =
                productionReportReadService.pagingProductionReportByArea(pageNo,pageSize,start,end,breedFactoryIds);
        if(!pagingResponse.isSuccess()){
            log.error("failed to paging production reports error ={}",pagingResponse.getError());
            throw new OPServerException(ExceptionCode.DATA_NOT_FOUND.value(),pagingResponse.getError());
        }

        return pagingResponse.getResult();
    }

    @OpenMethod(
            key = "count.sum.by.third.type",
            paramNames = {"breedFactoryId"},
            httpMethods = RequestMethod.GET
    )
    public List<Map<String , Object>> countSumByThirdType(Long breedFactoryId){
        if(breedFactoryId == null){
            log.error("breedFactoryId should be not null");
            throw new OPClientException(ExceptionCode.ID_NOT_EXIST.value(),
                    "breedFactoryId should be not null");
        }

        Response<List<Map<String , Object>>> response = productionReportReadService.countSumByThirdType(breedFactoryId);

        if(!response.isSuccess()){
            log.error("failed to sum change quantity by third type error = {}",response.getError());
            throw new OPServerException(ExceptionCode.DATA_NOT_FOUND.value(),response.getError());
        }

        return response.getResult();
    }
}
